package framework.webmvc.component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * the class that show the view
 * main function render to show the view (in this project it just write a sentence)
 */
public class InchView {
    //default content type
    public static final String DEFAULT_CONTENT_TYPE = "text/html;charset=utf-8";
    //the file that store the view
    private File viewFile;

    /**
     * constructor
     * @param viewFile the file of view
     */
    public InchView(File viewFile) {
        this.viewFile = viewFile;
    }

    public String getDefaultContentType() {
        return DEFAULT_CONTENT_TYPE;
    }

    /**
     * Main method to show the view
     * @param model
     * @param request
     * @param response
     * @throws IOException
     * @throws FileNotFoundException
     */
    public void render( HttpServletRequest request, HttpServletResponse response,Map<String,?> model)
            throws IOException, FileNotFoundException {
        //read from view file
        StringBuffer stringBuffer = new StringBuffer();
        RandomAccessFile ra = null;
        ra = new RandomAccessFile(this.viewFile,"r");
        String line = null;
        //read each line
        while ((line = ra.readLine()) != null) {
            line = new String(line.getBytes("ISO-8859-1"),"utf-8");
            //find the param we need in certain form eg: from  "${name}" we find "name"
            Pattern pattern = Pattern.compile("\\$\\{[^\\}]+\\}",Pattern.CASE_INSENSITIVE);
            Matcher matcher = pattern.matcher(line);
            while (matcher.find()) {
                //get the match sequence eg: "${name}"
                String paramName = matcher.group();
                //get the real name eg: "name"
                paramName = paramName.replaceAll("\\$\\{|\\}","");
                //get the value of this parameter
                Object paramValue = model.get(paramName);
                //check the value
                if (paramValue == null) { continue; }
                //replace the params in the html eg: replace "${name}" with the sent param value"ian"
                line = matcher.replaceFirst(makeStringForRegExp(paramValue.toString()));
                matcher = pattern.matcher(line);
            }
            stringBuffer.append(line);
        }
        ra.close();
        response.setCharacterEncoding("utf-8");
        response.getWriter().write(stringBuffer.toString());
    }

    /**
     * deal with special char like "\" "&"
     * @param str the string may contains these chars
     * @return the regex format of these char
     */
    public static String makeStringForRegExp(String str) {
        return str.replace("\\","\\\\").replace("*","\\")
                .replace("+","\\+").replace("|","\\|")
                .replace("{","\\{").replace("}","\\}")
                .replace("(","\\(").replace(")","\\)")
                .replace("[","\\[").replace("]","\\]")
                .replace("^","\\^").replace("$","\\$")
                .replace("?","\\?").replace(",","\\,")
                .replace(".","\\.").replace("&","\\&");
    }


}
